"""
演示如何设置软件的外观，图表的参数，以及基本的使用方法等。

Stone at GDOU， 2020
"""
from pygame_scope import Scope

# ===== ===== ===== ===== =====
# 外观设置
# ===== ===== ===== ===== =====
# 初始化示波器（示波器也是程序窗口）
scope = Scope(sizex=600, sizey=300) # 窗口尺寸，单位像素

# 示波器基本设置（默认为 y-t 模式）
scope.axes.bgc = (0,0,0)    # 设置绘图区背景颜色（bg color）

yaxis = scope.axes.yaxis
yaxis.color = (255,255,0)       # 设置y轴的颜色
yaxis.font_color = (255,255,0)  # 设置y轴刻度字体的颜色
yaxis.font_size = 26            # 设置y轴刻度字体的大小
yaxis.lim_upper =  2            # 设置y轴数值上限(limit upper)
yaxis.lim_lower = -2            # 设置y轴数值下限
yaxis.tick_step = 1             # 每相邻两个刻度之间相差多少数值
yaxis.spline_thickness = 2      # 坐标轴线宽

scope.panel.min_value = 0       # 拖动条最小取值
scope.panel.max_value = 3       # 拖动条最大取值
scope.panel.value = 1          # 设置滑块的值
# val = scope.value             # 获取滑块的值

scope.axes.drawer.x_step = 5    # 设置x轴步长(x方向上，曲线上每两个采样点相距几个像素)


# x-y 模式设置（区别仅为 x-y 模式下会绘制 x轴）

# scope.axes.mode_xy = True                                     # step 1. 启用 x-y 模式
# cxy = scope.axes.create_curve([255,255,0], curve_type='x-y')  # step 2. 创建 x-y 曲线对象，注意curve_type参数
# cxy.append_sample((x, y))                                     # step 3. 向 x-y 曲线对象传入数值对
# cxy.n_points = 100        # 储存多少采样点
# cxy.connected = True      # 是否在将采样点用直线连起来
# cxy.draw_points = True    # 是否绘制采样点
# cxy.pt_radius = 2         # 采样点的半径
# cxy.thickness = 1         # 曲线线宽

xaxis = scope.axes.xaxis
xaxis.color = (255,255,0)       # 设置x轴的颜色
xaxis.font_color = (255,255,0)  # 设置x轴刻度字体的颜色
xaxis.lim_upper =  2            # 设置x轴数值上限(limit upper)
xaxis.lim_lower = -2            # 设置x轴数值下限
xaxis.tick_step = 1             # 每相邻两个刻度之间相差多少数值


# 程序中有一个默认的曲线对象，传给scope.append_sample(val)的值都通过这个对象绘制。
# 绘制两条以上的曲线，需通过c = scope.axes.create_curve(color)创建新的曲线对象，
# 然后调用c.append_sample(val)将数值绘制在新的曲线上。
scope.axes.default_curve.color = (0, 255, 255)  # 默认曲线的颜色


#暂不支持直接设置曲线线宽；字体大小可在对应类（YAxis、TrackBar）中修改
scope.apply()   # 使上面的设置生效



# ===== ===== ===== ===== =====
# 示例代码
# ===== ===== ===== ===== =====
def example_1():
    """绘制一条正弦曲线"""
    import math, time
    
    for i in range(1, 20):
        val = math.sin(2*math.pi*i/20)
        scope.append_sample(val)  # 绘制数值
        scope.show()  # 一定要记得调用scope.show()显示结果
        
        time.sleep(0.01)  # 整个循环运行完的需要的时间应当很短


# 创建曲线对象
c1 = scope.axes.create_curve((255, 0, 0))  # 参数为曲线的颜色
c2 = scope.axes.create_curve((0, 255, 0))
c3 = scope.axes.create_curve((0, 0, 255))
def example_2():
    """绘制多条曲线"""
    import math, time, random
    
    n = 30
    for i in range(1, n):
        # 画正弦曲线
        val = math.sin(2*math.pi*i/n)
        scope.append_sample(val)  # 绘制数值
        
        # 画方波
        if i < n/2:
            c1.append_sample(0)
        else:
            c1.append_sample(1.2)
        
        # 画锯齿波
        c2.append_sample(i/n)
        
        # 画随机数
        c3.append_sample(random.random() - 1.5)
        
        scope.show()  # 一定要记得调用scope.show()显示结果
        time.sleep(0.01)  # 整个循环运行完的需要的时间应当很短


def example_3():
    """用滑块控制正弦波的幅度"""
    import math, time
    
    for i in range(1, 20):
        A = scope.panel.value
        
        val = A * math.sin(2*math.pi*i/20)
        scope.append_sample(val)  # 绘制数值
        scope.show()  # 一定要记得调用scope.show()显示结果
        
        time.sleep(0.01)  # 整个循环运行完的需要的时间应当很短


def example_4():
    """在 x-y 模式下绘制李萨如图形"""
    import math
    
    # step 1. 启用 x-y 模式
    scope.axes.mode_xy = True
    scope.apply()
    
    # step 2. 创建 x-y 曲线对象
    cxy = scope.axes.create_curve([255,255,0], curve_type='x-y')  # curve_type 为字符串'x-y'
    cxy.n_points = 50
    # cxy.connected = True
        
    t = 0
    角速度 = 0.1
    while True:
        A = scope.panel.value
        
        x = A * math.sin(角速度*t)
        y = A * math.cos(3*角速度*t)
        cxy.append_sample((x, y))  # step 3. 向 x-y 曲线对象传入数值对
        
        scope.show()  # 一定要记得调用scope.show()显示结果
        
        t += 1
        yield   # 利用生成器的语法来运行循环
example_4 = example_4()

# 假装是主函数，注册进scope.mainloop()。scope.mainloop()在其每次循环中处理完事件后，
# 调用该函数一次。
# 也就是说，该函数中不能有循环或时间太长的操作，否则将造成程序无法响应事件。
def fake_main():
    # example_1()
    # example_2()
    # example_3()
    next(example_4)
   
    

if __name__ == '__main__':
    scope.mainloop(user_task=fake_main)
    
    